package com.xiaoq.sites.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.apis.order.ISPUApi;
import com.xiaoq.apis.user.FollowInfo4InterpreterVo;
import com.xiaoq.apis.user.IUserApi;
import com.xiaoq.apis.user.UserInfo4UserCouponVo;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.sites.entity.InterDicEntity;
import com.xiaoq.sites.entity.InterpreterEntity;
import com.xiaoq.sites.service.IInterDicService;
import com.xiaoq.sites.service.IInterpreterService;
import com.xiaoq.sites.vo.InterCalendarDetailVo;
import com.xiaoq.sites.vo.InterpreterVo;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.MultiKeyMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/v1")
@Api(tags = "C端讲解员")
public class InterpreterEndpoint {
	
	private static final class InterpreterListResponse extends GenericListResponse<InterpreterVo> {}
	private static final class InterpreterVoResponse extends GenericDataResponse<InterpreterVo> {}
	private static final class InterCalendarResponse extends GenericDataResponse<InterCalendarDetailVo> {}
	private static final class InterpreterCountResponse extends GenericDataResponse<InterpreterCountVo> {}

	private Logger logger = LoggerFactory.getLogger(InterpreterEndpoint.class);
	
	//@Reference(interfaceClass=IInterpreterApi.class, check=false, version="1.0.0")
	@Autowired
	private IInterpreterService interpreterService;

	@Autowired
	private IInterDicService interDicService;

	@Reference(interfaceClass=IUserApi.class, check=false, version="1.0.0")
	private IUserApi userDubboApi;

	@Reference(interfaceClass=ISPUApi.class, check=false, version="1.0.0")
	private ISPUApi spuApi;
	
	@ApiOperation(value="查询可预约讲解员列表", notes="根据景区ID查询讲解员列表")
	@ApiResponses({
		@ApiResponse(code = 200, response = InterpreterListResponse.class, message = "查询可预约讲解员列表")
	})
	@GetMapping(value="/sites/{sitesId}/interpreter", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> interpreterList(@PathVariable("sitesId") @ApiParam(value="景区ID", required=true) String sitesId,
											 HttpServletRequest request) {

		String userId = (String) request.getAttribute("userId");

		InterpreterVo interpreterVo = null;
		List<InterpreterVo> interpreterVoList = new ArrayList<>();
		List<InterpreterEntity> interpreterEntityList = interpreterService.findInterpreterListBySitesId(sitesId,
				ConstantUtil.INTERPRETER_STATUS_WAIT_SERVICE_CAN_APPOINT, null);

		MultiKeyMap multiKeyMap = getMultiKeyMap();

		if(CollectionUtils.isNotEmpty(interpreterEntityList)) {
			List<String> targetIdList = new ArrayList<>(); //讲解员ID列表
			for (InterpreterEntity interpreterEntity : interpreterEntityList) {
				interpreterVo = new InterpreterVo();
				BeanUtils.copyProperties(interpreterEntity, interpreterVo);
				interpreterVo.setPrice(interpreterEntity.getPrice()/100.0);
				targetIdList.add(interpreterEntity.getId());
				//处理数据字典 begin
				List<String> langList = interpreterVo.getSvcLang();
				fillInterDicVal(multiKeyMap, interpreterVo, langList);
				String experienceVal = (String) multiKeyMap.get(ConstantUtil.DIC_TYPE_4_INTER_EXPERIENCE, interpreterVo.getSvcExperience());
				if(experienceVal != null){
					interpreterVo.setSvcExperience(experienceVal);
				}
				//处理数据字典 end

				interpreterVoList.add(interpreterVo);
			}

			List<FollowInfo4InterpreterVo> followList = null;
			try {
				followList = userDubboApi.getFollowList(userId, targetIdList, "40"); //40 为景区的关注
			}catch (Exception e){
				logger.error("获取用户关注讲解员dubbo失败");
				logger.error(e.getMessage(), e);
			}

			Map<String, Double> interId2ScoreMap = null;
			try {
				interId2ScoreMap = spuApi.getReviewScore4InterByShopId(sitesId);
			}catch (Exception e){
				logger.error("获取讲解员的评分dubbo失败");
				logger.error(e.getMessage(), e);
			}
			if(interId2ScoreMap == null){
				interId2ScoreMap = new HashMap<>();
			}
			Set<String> targetIdSets = new HashSet<>();
			if(CollectionUtils.isNotEmpty(followList)){
				targetIdSets = followList.stream().map(follow->follow.getTargetId()).collect(Collectors.toSet());
			}

			for (InterpreterVo tmpInterVo : interpreterVoList){
				String interId = tmpInterVo.getId();

				if(targetIdSets.contains(interId)){
					tmpInterVo.setFollow(1); //关注
				}else{
					tmpInterVo.setFollow(0); //未关注
				}

				if(interId2ScoreMap.get(interId) != null){
					tmpInterVo.setAvgStar(interId2ScoreMap.get(interId));
				}else {
					tmpInterVo.setAvgStar(0D);
				}
			}
		}

		return InterpreterListResponse.listNoCount(interpreterVoList);
	}

	@ApiOperation(value="查询可预约讲解员数量", notes="查询可预约讲解员数量")
	@ApiResponses({
			@ApiResponse(code = 200, response = InterpreterCountResponse.class, message = "查询可预约讲解员数量")
	})
	@GetMapping(value="/sites/{sitesId}/interpreter/canappointcount", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> interpreterCanAppointList(@PathVariable("sitesId") @ApiParam(value="景区ID", required=true) String sitesId,
											 HttpServletRequest request) {

		String userId = (String) request.getAttribute("userId");
		InterpreterCountVo countVo = new InterpreterCountVo();
		long count = interpreterService.findInterpreterListCountBySitesId(sitesId,
				ConstantUtil.INTERPRETER_STATUS_WAIT_SERVICE_CAN_APPOINT);
		countVo.setCount(count);
		return InterpreterCountResponse.okWithData(countVo);
	}

	@ApiOperation(value="查询讲解员日历列表", notes="根据讲解员ID查询讲解员日历列表")
	@ApiResponses({
			@ApiResponse(code = 200, response = InterCalendarResponse.class, message = "讲解员日历列表")
	})
	@GetMapping(value="/inter/{interpreterId}/calendar", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> interCalendarList(@PathVariable("interpreterId") @ApiParam(value="讲解员ID", required=true) String interpreterId,
													 HttpServletRequest request) {

		String errorMsg = "查询讲解员日历列表";
		try {
			String userId = (String) request.getAttribute("userId");
			UserInfo4UserCouponVo userInfo = userDubboApi.getUserInfoById(userId);
			if(userInfo==null || StringUtils.isBlank(userInfo.getId())){
				return GenericResponse.ng("该用户不存在或未登录");
			}

			InterpreterEntity interpreterEntity = interpreterService.findInterpreterById(interpreterId);
			if(interpreterEntity == null || StringUtils.isBlank(interpreterEntity.getId())){
				return GenericResponse.ng("该讲解员不存在");
			}
			InterCalendarDetailVo interCalendarDetailVo = interpreterService.getNearly7DaysNoInterServiceCalendarList(
					interpreterEntity.getUserId(), interpreterEntity.getSitesId());
			if(interCalendarDetailVo == null){
				return GenericResponse.ng("该讲解员日历不存在");
			}
			interCalendarDetailVo.setPrice(interpreterEntity.getPrice()/100.0);
			interCalendarDetailVo.setSitesId(interpreterEntity.getSitesId());
			interCalendarDetailVo.setInterpreterId(interpreterEntity.getUserId());
			return InterCalendarResponse.okWithData(interCalendarDetailVo);
		} catch (Exception e) {
			logger.error(errorMsg,e);
			return GenericResponse.ng(errorMsg);
		}
	}

	@ApiOperation(value="查询讲解员的状态（是否可预约）", notes="查询讲解员的状态（是否可预约）")
	@ApiResponses({
			@ApiResponse(code = 200, response = GenericResponse.class, message = "查询讲解员的状态（是否可预约）")
	})
	@GetMapping(value="/inter/{interpreterId}/status", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> interStatus(@PathVariable("interpreterId") @ApiParam(value="讲解员ID", required=true) String interpreterId,
											   HttpServletRequest request) {

		String errorMsg = "查询讲解员的状态错误";
		try {
			String userId = (String) request.getAttribute("userId");
			UserInfo4UserCouponVo userInfo = userDubboApi.getUserInfoById(userId);
			if(userInfo==null || StringUtils.isBlank(userInfo.getId())){
				return GenericResponse.ng("该用户不存在或未登录");
			}

			InterpreterEntity interpreterEntity = interpreterService.findInterpreterById(interpreterId);
			if(interpreterEntity==null || interpreterEntity.getStatus()==null){
				return GenericResponse.ng("该讲解员不存在或讲解员的状态不对");
			}

			if(ConstantUtil.INTERPRETER_STATUS_WAIT_SERVICE_CAN_APPOINT.equals(interpreterEntity.getStatus())){
				return GenericResponse.ok();
			}

			return GenericResponse.ng("此讲解员此时暂不可预约");
		} catch (Exception e) {
			logger.error(errorMsg,e);
			return GenericResponse.ng(errorMsg);
		}
	}

	@ApiOperation(value="查询讲解员", notes="查询讲解员")
	@ApiResponses({
			@ApiResponse(code = 200, response = InterpreterVoResponse.class, message = "查询讲解员")
	})
	@GetMapping(value="/inter/{interpreterId}/detail", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> detail(@PathVariable("interpreterId") @ApiParam(value="讲解员ID", required=true) String interpreterId,
										 HttpServletRequest request) {

		String userId = (String) request.getAttribute("userId");
		UserInfo4UserCouponVo userInfo = userDubboApi.getUserInfoById(userId);
		if(userInfo==null || StringUtils.isBlank(userInfo.getId())){
			return GenericResponse.ng("该用户不存在或未登录");
		}

		InterpreterEntity interpreterEntity = interpreterService.findInterpreterById(interpreterId);
		if(interpreterEntity==null || interpreterEntity.getStatus()==null){
			return GenericResponse.ng("该讲解员不存在或讲解员的状态不对");
		}

		//查询所有的数据字典字典
		MultiKeyMap multiKeyMap = getMultiKeyMap();

		InterpreterVo interpreterVo = new InterpreterVo();
		BeanUtils.copyProperties(interpreterEntity, interpreterVo);
		interpreterVo.setPrice(interpreterEntity.getPrice() / 100.0);
		String interId = interpreterVo.getId();

		//处理数据字典 begin
		List<String> langList = interpreterVo.getSvcLang();
		fillInterDicVal(multiKeyMap, interpreterVo, langList);
		String experienceVal = (String) multiKeyMap.get(ConstantUtil.DIC_TYPE_4_INTER_EXPERIENCE, interpreterVo.getSvcExperience());
		if(experienceVal != null){
			interpreterVo.setSvcExperience(experienceVal);
		}
		//处理数据字典 end


		List<FollowInfo4InterpreterVo> followList = null;
		try {
			followList = userDubboApi.getFollowList(userId, Arrays.asList(interId), "40"); //40 为景区的关注
		}catch (Exception e){
			logger.error("获取用户关注讲解员dubbo失败");
			logger.error(e.getMessage(), e);
		}

		Map<String, Double> interId2ScoreMap = null;
		try {
			interId2ScoreMap = spuApi.getReviewScore4InterByShopId(interpreterEntity.getSitesId());
		}catch (Exception e){
			logger.error("获取讲解员的评分dubbo失败");
			logger.error(e.getMessage(), e);
		}

		if(interId2ScoreMap == null){
			interId2ScoreMap = new HashMap<>();
		}
		Set<String> targetIdSets = new HashSet<>();
		if(CollectionUtils.isNotEmpty(followList)){
			targetIdSets = followList.stream().map(follow->follow.getTargetId()).collect(Collectors.toSet());
		}

		if(targetIdSets.contains(interId)){
			interpreterVo.setFollow(1); //关注
		}else{
			interpreterVo.setFollow(0); //未关注
		}

		if(interId2ScoreMap.get(interId) != null){
			interpreterVo.setAvgStar(interId2ScoreMap.get(interId));
		}else {
			interpreterVo.setAvgStar(0D);
		}

		return InterpreterVoResponse.okWithData(interpreterVo);
	}

	private void fillInterDicVal(MultiKeyMap multiKeyMap, InterpreterVo interpreterVo, List<String> langList) {
		if(CollectionUtils.isNotEmpty(langList)){
			List<String> dicValueList = new ArrayList<>();
			for(String lang : langList){
				String dicValue = (String) multiKeyMap.get(ConstantUtil.DIC_TYPE_4_INTER_LANG,lang);
				if(dicValue != null){
					dicValueList.add(dicValue);
				}
			}
			interpreterVo.setSvcLang(dicValueList);
		}
	}

	public static class InterpreterCountVo {
		@ApiModelProperty(name = "count", value = "讲解员数量", position=10)
		private long count;

		public long getCount() {
			return count;
		}

		public void setCount(long count) {
			this.count = count;
		}
	}


	/**
	 *  获取数据字典
	 * @return <key,key,value>  <dicType,dicId,dicValue>
	 */
	private MultiKeyMap getMultiKeyMap(){
		//查询所有的数据字典字典
		List<InterDicEntity> interDicList = interDicService.getAllInterDicList(null, null);
		MultiKeyMap multiKeyMap = new MultiKeyMap(); //
		if(CollectionUtils.isNotEmpty(interDicList)){
			for(InterDicEntity interDicEntity : interDicList){
				multiKeyMap.put(interDicEntity.getDicType(), interDicEntity.getDicId(), interDicEntity.getDicValue());
			}
		}
		return multiKeyMap;
	}


}
